package app

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"
	"time"

	"gitee.com/tomatomeatman/golang-repository/bricks/model"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/function/data"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/function/system"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/gorm"
	Log "github.com/cihub/seelog"
	"github.com/gin-gonic/gin"
	uuid "github.com/satori/go.uuid"
)

var (
	recordKeyJam = "" //创建sRecordKey用的干扰串
	upFilePath   = "" //上传文件路径
)

type CommonService struct{}

/**
 * 新增
 * entity 检查用数据结构
 * data 数据
 */
func (service CommonService) Add(ctx *gin.Context, entity interface{}, data map[string]interface{}) *model.MsgEmity {
	// if (system.ReflectUtils{}.HasField(entity, "GsPid")) {
	// 	return service.AddNode(ctx, entity, data)
	// }

	return service.AddCommon(ctx, entity, data)
}

/**
 * 新增普通数据
 * entity 检查用数据结构
 * data 数据
 */
func (service CommonService) AddCommon(ctx *gin.Context, entity interface{}, aData map[string]interface{}) *model.MsgEmity {
	data.StringUtil{}.TrimAttribute(aData) //清除对象各个属性的值的前后空格

	//data.MapUtil{}.RemoveData(data, []string{"uId", "sId", "iId", "sCreator", "sModifieder", "dCreateDate", "dModifiedDate"}) //清理不能由前端定义的字段
	data.MapUtil{}.RemoveData(aData, []string{model.TableMajorKeyString, model.TableMajorKeyAutoInt, model.TableMajorKeyUuId, model.TableCreatorName, model.TableCreateDateName, model.TableModifiederName, model.TableModifiedDateName, model.TableVersionName}) //清理不能由前端定义的字段

	//me := model.DataInfo{}.ValidAttr(data, entity, []string{"uId", "sId", "iId", "sCreator", "sModifieder", "dCreateDate", "dModifiedDate"}) //对对象中添加了model.DataInfo注解的不为nil的属性检查限制
	me := model.DataInfo{}.ValidAttr(aData, entity, []string{model.TableMajorKeyString, model.TableMajorKeyAutoInt, model.TableMajorKeyUuId, model.TableCreatorName, model.TableCreateDateName, model.TableModifiederName, model.TableModifiedDateName}) //对对象中添加了model.DataInfo注解的不为nil的属性检查限制
	if !me.Gsuccess {
		return me.IncCode(7000)
	}

	me = model.DataInfo{}.MapToEntity(aData, entity)
	if !me.Gsuccess {
		return me.IncCode(7010)
	}

	commons := me.Gdata
	commons = model.DataInfo{}.SetDataInfoDefault(commons) //对对象中添加了dataInfo注解的属性添加默认值
	fmt.Println(commons)

	me = service.SupplyDbEntityAttrByAdd(ctx, commons, "", "")
	if !me.Gsuccess {
		return me.IncCode(7030)
	}

	me = model.DataInfo{}.ValidAttrByAdd(commons, []string{}) //对对象中添加了model.DataInfo注解的属性检查限制
	if !me.Gsuccess {
		return me.IncCode(7020)
	}

	me = service.ValidEntityRepeatByAdd(ctx, commons) //验证新增数据是否存在重复
	if !me.Gsuccess {
		return me.IncCode(7030)
	}

	return CommonDao{}.AddCommon(commons)
}

/**
 * 新增树节点
 * entity 检查用数据结构
 * data 数据
 */
func (service CommonService) AddNode(ctx *gin.Context, entity interface{}, aData map[string]interface{}) *model.MsgEmity {
	data.StringUtil{}.TrimAttribute(aData) //清除对象各个属性的值的前后空格

	//data.MapUtil{}.RemoveData(data, []string{"uId", "sId", "iId", "sCreator", "sModifieder", "dCreateDate", "dModifiedDate"}) //清理不能由前端定义的字段
	data.MapUtil{}.RemoveData(aData, []string{model.TableMajorKeyString, model.TableMajorKeyAutoInt, model.TableMajorKeyUuId, model.TableCreatorName, model.TableCreateDateName, model.TableModifiederName, model.TableModifiedDateName, model.TableVersionName}) //清理不能由前端定义的字段

	//me := model.DataInfo{}.ValidAttr(data, entity, []string{"uId", "sId", "iId", "sCreator", "sModifieder", "dCreateDate", "dModifiedDate"}) //对对象中添加了model.DataInfo注解的不为nil的属性检查限制
	me := model.DataInfo{}.ValidAttr(aData, entity, []string{model.TableMajorKeyString, model.TableMajorKeyAutoInt, model.TableMajorKeyUuId, model.TableCreatorName, model.TableCreateDateName, model.TableModifiederName, model.TableModifiedDateName}) //对对象中添加了model.DataInfo注解的不为nil的属性检查限制
	if !me.Gsuccess {
		return me.IncCode(7000)
	}

	me = model.DataInfo{}.MapToEntity(aData, entity)
	if !me.Gsuccess {
		return me.IncCode(7010)
	}

	commons := me.Gdata
	model.DataInfo{}.SetDataInfoDefault(commons) //对对象中添加了dataInfo注解的属性添加默认值

	me = service.SupplyDbEntityAttrByAdd(ctx, commons, "", "")
	if !me.Gsuccess {
		return me.IncCode(7030)
	}

	me = model.DataInfo{}.ValidAttrByAdd(commons, []string{}) //对对象中添加了model.DataInfo注解的属性检查限制
	if !me.Gsuccess {
		return me.IncCode(7020)
	}

	me = service.ValidEntityRepeatByAdd(ctx, commons) //验证新增数据是否存在重复
	if !me.Gsuccess {
		return me.IncCode(7030)
	}

	return CommonDao{}.AddNode(commons)
}

// 批量新增
func (service CommonService) Adds(ctx *gin.Context, entitys []interface{}, list []map[string]interface{}) *model.MsgEmity {
	if len(list) < 1 {
		return model.MsgEmity{}.Err(8001, "没有需要保存的数据")
	}

	entitysNew := []interface{}{}
	for k, vData := range list {
		data.StringUtil{}.TrimAttribute(vData) //清除对象各个属性的值的前后空格

		entity := entitys[k]

		data.MapUtil{}.RemoveData(vData, []string{model.TableMajorKeyString, model.TableMajorKeyAutoInt, model.TableMajorKeyUuId, model.TableCreatorName, model.TableCreateDateName, model.TableModifiederName, model.TableModifiedDateName, model.TableVersionName}) //清理不能由前端定义的字段

		me := model.DataInfo{}.ValidAttr(vData, entity, []string{model.TableMajorKeyString, model.TableMajorKeyAutoInt, model.TableMajorKeyUuId, model.TableCreatorName, model.TableCreateDateName, model.TableModifiederName, model.TableModifiedDateName}) //对对象中添加了model.DataInfo注解的不为nil的属性检查限制
		if !me.Gsuccess {
			return me.IncCode(7000)
		}

		me = model.DataInfo{}.MapToEntity(vData, entity)
		if !me.Gsuccess {
			return me.IncCode(7010)
		}

		commons := me.Gdata
		model.DataInfo{}.SetDataInfoDefault(commons) //对对象中添加了dataInfo注解的属性添加默认值

		me = service.SupplyDbEntityAttrByAdd(ctx, commons, "", "")
		if !me.Gsuccess {
			return me.IncCode(7030)
		}

		me = model.DataInfo{}.ValidAttrByAdd(commons, []string{}) //对对象中添加了model.DataInfo注解的属性检查限制
		if !me.Gsuccess {
			return me.IncCode(7020)
		}

		me = service.ValidEntityRepeatByAdd(ctx, commons) //验证新增数据是否存在重复
		if !me.Gsuccess {
			return me.IncCode(7030)
		}

		entitysNew = append(entitysNew, commons)
	}

	return CommonDao{}.Adds(entitysNew)
}

// 批量新增
func (service CommonService) AddList(ctx *gin.Context, entitys []interface{}) *model.MsgEmity {
	if len(entitys) < 1 {
		return model.MsgEmity{}.Err(8001, "没有需要保存的数据")
	}

	for _, entity := range entitys {
		model.DataInfo{}.SetDataInfoDefault(entity) //对对象中添加了dataInfo注解的属性添加默认值
		me := service.SupplyDbEntityAttrByAdd(ctx, entity, "", "")
		if !me.Gsuccess {
			return me.IncCode(7030)
		}
	}

	return CommonDao{}.Adds(entitys)
}

/**
 * 修改状态
 * @param entity 实体类
 * @param id 编号
 * @param iState 状态值
 * @param iVersion 记录版本号
 * @param sMemo 备注
 * @param unidirectional 是否单向 设置为单向则新值必须大于旧值才能执行
 * @return model.MsgEmity 返回执行情况
 */
func (service CommonService) ChangeState(ctx *gin.Context, entity interface{}, id interface{}, iState int, iVersion int, sMemo string, unidirectional bool) *model.MsgEmity {
	if "" == fmt.Sprintf("%v", id) {
		return model.MsgEmity{}.Err(8001, "记录编号参数为空！")
	}

	return CommonDao{}.ChangeState(entity, id, iState, iVersion, sMemo, unidirectional)
}

/**
 * 修改步骤值(如果设置为单向则新值必须大于旧值)
 * @param id 编号
 * @param iSetp 步骤值
 * @param iVersion 记录版本号
 * @param sMemo 备注
 * @param unidirectional 是否单向 设置为单向则新值必须大于旧值才能执行
 * @param entity 实体类
 * @return model.MsgEmity 返回执行情况
 */
func (service CommonService) ChangeSetp(ctx *gin.Context, entity interface{}, id interface{}, iSetp int, iVersion int, sMemo string, unidirectional bool) *model.MsgEmity {
	if "" == fmt.Sprintf("%v", id) {
		return model.MsgEmity{}.Err(8001, "记录编号参数为空！")
	}

	return CommonDao{}.ChangeSetp(entity, id, iSetp, iVersion, sMemo, unidirectional)
}

/**
 * 删除
 * @param entity 对象类型
 * @param id 记录编号值
 * @param iVersion 记录版本号
 * @return model.MsgEmity
 */
func (service CommonService) Del(ctx *gin.Context, entity interface{}, id interface{}, iVersion int) *model.MsgEmity {
	if id == nil {
		return model.MsgEmity{}.Err(8001, "记录编号为空")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)

	if tableInfo.GbHasVersion && (iVersion < 1) && (iVersion != data.IntegerUtil{}.MaxInt()) {
		return model.MsgEmity{}.Err(8002, "记录版本号不正确")
	}

	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 7) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	physics := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 1) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除
	if !physics && tableInfo.GbHasDelSign {                      //有逻辑删除字段标识才能进行逻辑删除
		return CommonDao{}.DelSign(entity, id, iVersion, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator) //标识删除
	}

	return CommonDao{}.Del(entity, id, iVersion, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

/**
 * 删除
 * @param entity 对象类型
 * @param where 执行条件
 * @return model.MsgEmity
 */
func (service CommonService) DelByMap(ctx *gin.Context, entity interface{}, where map[string]interface{}) *model.MsgEmity {
	if entity == nil {
		return model.MsgEmity{}.Err(8001, "结构体参数为nil")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)

	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 7) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	physics := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 1) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除
	if !physics && tableInfo.GbHasDelSign {                      //有逻辑删除字段标识才能进行逻辑删除
		return CommonDao{}.DelSignByMap(entity, where, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator) //标识删除
	}

	return CommonDao{}.DelByMap(entity, where, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

/**
 * 按实体保留map中的数据
 * object 待检查对象
 * data 数据
 * fieldPrefix 字段前缀(可不传)
 */
func (service CommonService) HoldByEntity(entity interface{}, data map[string]interface{}, fieldPrefix ...string) map[string]interface{} {
	var rve reflect.Type
	typeOf := reflect.TypeOf(entity)  //通过反射获取type定义
	if typeOf.Kind() == reflect.Ptr { //是否指针类型
		rve = reflect.ValueOf(entity).Elem().Type() // 取得struct变量的指针
	} else if "reflect.Value" == typeOf.String() {
		rve = entity.(reflect.Value).Type()
	} else {
		rve = reflect.ValueOf(entity).Type()
	}

	result := map[string]interface{}{}
	for _, prefix := range fieldPrefix {
		for key, value := range data {
			str := key
			if "" != prefix {
				str = prefix + key
			}

			field, b := rve.FieldByName(str)
			if !b {
				continue
			}

			str = field.Tag.Get("dataInfo")
			if "" != str {
				result[key] = value
			}
		}
	}

	return data

	//typeOf := reflect.TypeOf(entity) //通过反射获取type定义

	//if typeOf.Kind() == reflect.Ptr { //是否指针类型
	//	typeOf = typeOf.Elem()
	//}

	//prefix := ""
	//for _, key := range fieldPrefix {
	//	prefix = prefix + key
	//}

	//for key, _ := range data {
	//	str := key
	//	if "" != prefix {
	//		str = prefix + key
	//	}

	//	_, b := typeOf.FieldByName(str)
	//	if !b {
	//		delete(data, key)
	//	}
	//}

	//return data
}

func (service CommonService) getBaseEntity(entity interface{}) interface{} {
	var rte reflect.Type
	var rve reflect.Value
	typeOf := reflect.TypeOf(entity)  //通过反射获取type定义
	if typeOf.Kind() == reflect.Ptr { //是否指针类型
		rve = reflect.ValueOf(entity).Elem()
		rte = rve.Type() // 取得struct变量的指针
	} else if "reflect.Value" == typeOf.String() {
		rve = entity.(reflect.Value)
		rte = rve.Type()
	} else {
		rve = reflect.ValueOf(entity)
		rte = reflect.ValueOf(entity).Type()
	}

	for k := 0; k < rte.NumField(); k++ {
		field := rte.Field(k)
		if field.Anonymous && strings.HasSuffix(field.Name, "Base") {
			return rve.Field(k) //找到
		}
	}

	return entity //没找到
}

/**
 * 修改
 * @param entity 对象类型
 * @param id 记录编号值
 * @param iVersion 记录版本号
 * @param data 待更新的字段和值
 * @return model.MsgEmity
 */
func (service CommonService) Edit(ctx *gin.Context, entity interface{}, id interface{}, iVersion int, aData map[string]interface{}) *model.MsgEmity {
	if "" == fmt.Sprintf("%v", id) {
		return model.MsgEmity{}.Err(7001, "记录编号参数为空！")
	}

	baseEntity := system.ReflectUtils{}.GetBaseEntity(entity)              //取基础数据库实体
	aData = system.ReflectUtils{}.HoldByEntity(baseEntity, aData, "", "G") //按实体保留map中的数据
	// data.MapUtil{}.RemoveData(data, []string{"uId", "sId", "iId", "sPath", "sCreator", "sModifieder", "dCreateDate", "dModifiedDate", "iVersion",
	// 	"u_id", "s_id", "i_id", "s_path", "s_creator", "s_modifieder", "d_create_date", "d_modified_date", "i_version"}) //清理不能由前端定义的字段
	data.MapUtil{}.RemoveData(aData, []string{model.TableMajorKeyString, model.TableMajorKeyAutoInt, model.TableMajorKeyUuId, model.TablePathKey, model.TableCreatorName, model.TableCreateDateName, model.TableModifiederName, model.TableModifiedDateName}) //清理不能由前端定义的字段

	if len(aData) < 1 {
		return model.MsgEmity{}.Err(7002, "更新操作提供的参数为空！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(baseEntity)

	if tableInfo.GbHasVersion && (1 > iVersion) {
		return model.MsgEmity{}.Err(7003, "记录版本号参数必须大于0！")
	}

	data.StringUtil{}.TrimAttribute(aData) //清除对象各个属性的值的前后空格

	// me := model.DataInfo{}.ValidAttr(data, baseEntity, []string{"uId", "sId", "iId", "sCreator", "sModifieder", "dCreateDate", "dModifiedDate", //对对象中添加了model.DataInfo注解的不为nil的属性检查限制
	// 	"u_id", "s_id", "i_id", "s_path", "s_creator", "s_modifieder", "d_create_date", "d_modified_date", "i_version"})  //对对象中添加了model.DataInfo注解的不为nil的属性检查限制
	me := model.DataInfo{}.ValidAttr(aData, baseEntity, []string{model.TableMajorKeyString, model.TableMajorKeyAutoInt, model.TableMajorKeyUuId, model.TablePathKey, model.TableCreateDateName, model.TableModifiedDateName}) //对对象中添加了model.DataInfo注解的不为nil的属性检查限制

	if !me.Gsuccess {
		return me.IncCode(7020)
	}

	me = service.ValidEntityRepeatByEdit(ctx, baseEntity, id, aData) //验证更新数据是否存在重复
	if !me.Gsuccess {
		return me.IncCode(7030)
	}

	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 6) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.Edit(baseEntity, id, iVersion, aData, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

/**
 * 根据主键查询数据
 * id 主键
 * entity 检查用数据结构
 */
func (service CommonService) FindById(ctx *gin.Context, entity interface{}, id interface{}) *model.MsgEmity {
	if id == nil {
		return model.MsgEmity{}.Err(1001, "记录编号为空")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)

	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.FindById(entity, id, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

// 查询所有数据
func (service CommonService) FindAll(ctx *gin.Context, entity interface{}, where map[string]interface{}) *model.MsgEmity {
	tableInfo := model.TableInfo{}.GetByEntity(entity)

	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.FindAll(entity, where, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

// 查询指定时间内数据
func (service CommonService) FindByDate(ctx *gin.Context, entity interface{}, sDateSt string, sDateEd string) *model.MsgEmity {
	tableInfo := model.TableInfo{}.GetByEntity(entity)

	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.FindByDate(entity, sDateSt, sDateEd, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

// 查询指定行数据
func (service CommonService) FindByRow(ctx *gin.Context, entity interface{}, id interface{}) *model.MsgEmity {
	if id == nil {
		return model.MsgEmity{}.Err(1001, "记录编号为空")
	}

	sId := fmt.Sprintf("%v", id)
	if sId == "" {
		return model.MsgEmity{}.Err(1002, "记录编号为空")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)

	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.FindByRow(entity, id, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

// 查询分页数据
func (service CommonService) FindByPage(ctx *gin.Context, entity interface{}, findByPageParam model.FindByPageParam) *model.MsgEmity {
	tableInfo := model.TableInfo{}.GetByEntity(entity)

	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.FindByPage(entity, findByPageParam, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

/**
 * 补充数据库实体类的数据--新增
 * @param dbEntity
 * @param selfId 自提供的编号,防止从序列中获取
 * @param idValuePrefix Id前缀
 * @return
 */
func (service CommonService) SupplyDbEntityAttrByAdd(ctx *gin.Context, dbEntity interface{}, selfId string, idValuePrefix string) *model.MsgEmity {
	if nil == dbEntity {
		return model.MsgEmity{}.Err(1001, "待存储的数据实体不能为nil")
	}

	model.DataInfo{}.SetDataInfoDefault(dbEntity) //对对象中添加了dataInfo注解的属性添加默认值

	sLoginUserId := ModuleUtil{}.CurrentLoginUserId(ctx) //取当前登录用户编号
	date := time.Now()

	system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableCreatorName, sLoginUserId)    // 设置当前操作用户
	system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableModifiederName, sLoginUserId) // 设置当前操作用户
	system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableCreateDateName, date)         // 设置新增时间
	system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableModifiedDateName, date)       // 设置修改时间
	system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableIndexName, 1)                 // 设置排序值
	system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableStateName, 1)                 // 设置状态值
	system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableVersionName, 1)               // 设置版本号

	tableInfo := model.TableInfo{}.GetByEntity(dbEntity)

	vNew := selfId
	if (model.TableMajorKeyUuId == tableInfo.GsKeyName) && "" == selfId { //按UUID设置值
		if tableInfo.GiKeyLen == 32 {
			vNew = strings.Replace(uuid.NewV4().String(), "-", "", -1) //取uuid
			system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableMajorKeyUuId, strings.ToUpper(vNew))
		} else if tableInfo.GiKeyLen == 22 {
			system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableMajorKeyUuId, data.U62Util{}.Get(idValuePrefix))
		} else {
			system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableMajorKeyUuId, data.U62Util{}.Get(idValuePrefix))
		}
	} else if (model.TableMajorKeyString == tableInfo.GsKeyName) && ("" == selfId) { //如果不是自增长,并且没有自定义id值,才能进行从序列中取新id的方法
		if tableInfo.GbHasPath { //对象中存在sPath,则id只需要4位
			pidValue := system.ReflectUtils{}.GetFieldValue(dbEntity, model.GtablePidKey)
			pid := fmt.Sprintf("%v", pidValue)
			if nil != pidValue {
				pid = model.TableTreeRootValue
			}

			me := CommonDao{}.NewChildId(tableInfo, pid)
			if !me.Gsuccess {
				return me
			}

			vNew = me.Gdata.(string)
			system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableMajorKeyString, vNew)
		} else if "" == idValuePrefix {
			vNew = ModuleUtil{}.GetNewId(tableInfo.GiKeyLen, tableInfo.GsTableName)
			system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableMajorKeyString, vNew)
		} else {
			iLength := tableInfo.GiKeyLen - len(idValuePrefix)
			vNew = idValuePrefix + ModuleUtil{}.GetNewId(iLength, tableInfo.GsTableName)
			system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableMajorKeyString, vNew)
		}
	}

	//--如果有sPid字段则进行部分处理--//
	if tableInfo.GbHasPid {
		sPid := system.ReflectUtils{}.GetFieldValue(dbEntity, model.GtablePidKey)
		if (nil == sPid) || ("" == sPid.(string)) { //如果sPid为空,则默认赋值'00'
			system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtablePidKey, model.GtableTreeRootValue)
		}
	}

	//--如果有sPath字段则进行部分处理--//
	if tableInfo.GbHasPath {
		sPid := system.ReflectUtils{}.GetFieldValue(dbEntity, model.GtablePidKey)
		sPath := system.ReflectUtils{}.GetFieldValue(dbEntity, model.GtablePathKey)

		if ((nil == sPath) || ("" == sPath.(string)) || ("/00/" == sPath.(string))) && (model.GtableTreeRootValue == sPid.(string)) { //如果sPid为空,则默认赋值'00'
			system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtablePathKey, "/00/"+vNew+"/")
		} else {
			sPath := CommonDao{}.GetPath(sPid.(string), tableInfo.GsDbName, tableInfo.GsTableName)
			system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtablePathKey, sPath+vNew+"/")
		}
	}

	//--如果有sRecordKey字段则进行部分处理--//
	if tableInfo.GbHasRecordKey {
		if "" == recordKeyJam {
			recordKeyJam = AppUtil{}.ReadConfigKey("App", "RecordKeyJam", "12345678").(string)
		}

		key := system.ReflectUtils{}.DoMethod(dbEntity, "CreateRecordKey", reflect.ValueOf(recordKeyJam))
		if len(key) > 0 {
			system.ReflectUtils{}.SetFieldValue(dbEntity, model.GtableRecordKeyName, key[0])
		}
	}

	return model.MsgEmity{}.Success(1999, "补充数据完毕！")
}

/**
 * 验证新增数据是否存在重复
 *
 */
func (service CommonService) ValidEntityRepeatByAdd(ctx *gin.Context, dbEntity interface{}) *model.MsgEmity {
	tableInfo := model.TableInfo{}.GetByEntity(dbEntity)
	customService := model.GlobalVariable{}.Get(tableInfo.GsTableName + "_ModuleService")

	//-- 树形结构 --//
	if tableInfo.GbHasPid {
		if nil == customService { //如果没有自定义业务层
			return service.CommonCheckRepeatByAddAndTree(ctx, dbEntity) //通用树型结构表添加数据时重复检查方法
		}

		method := system.ReflectUtils{}.GetMethod(customService, "CheckRepeatByAddAndTree")
		if !method.IsValid() { //如果自定义业务层定义了自检方法
			return service.CommonCheckRepeatByAddAndTree(ctx, dbEntity) //通用树型结构表添加数据时重复检查方法
		}

		result := system.ReflectUtils{}.DoMethod(customService, "CheckRepeatByAddAndTree", dbEntity)
		me := result[0].Interface()

		return me.(*model.MsgEmity)
	}

	//--不是树形数据则使用普通方法检查--//
	if nil == customService { //如果没有自定义业务层
		return service.CommonCheckRepeatByAdd(ctx, dbEntity) //通用添加数据时重复检查方法
	}

	method := system.ReflectUtils{}.GetMethod(customService, "CheckRepeatByAdd")
	if !method.IsValid() { //如果自定义业务层定义了自检方法
		return service.CommonCheckRepeatByAdd(ctx, dbEntity) //通用添加数据时重复检查方法
	}

	result := system.ReflectUtils{}.DoMethod(customService, "CheckRepeatByAdd", dbEntity)
	me := result[0].Interface()

	return me.(*model.MsgEmity)
}

/**
 * 验证更新数据是否存在重复
 *
 */
func (service CommonService) ValidEntityRepeatByEdit(ctx *gin.Context, entity interface{}, id interface{}, data map[string]interface{}) *model.MsgEmity {
	tableInfo := model.TableInfo{}.GetByEntity(entity)
	customService := model.GlobalVariable{}.Get(tableInfo.GsTableName + "_ModuleService")

	//-- 树形结构 --//
	if tableInfo.GbHasPid {
		if nil == customService { //如果没有自定义业务层
			return service.CommonCheckRepeatByEditAndTree(ctx, entity, id, data["sName"]) //通用树型结构表添加数据时重复检查方法
		}

		method := system.ReflectUtils{}.GetMethod(customService, "CheckRepeatByEditAndTree")
		if !method.IsValid() { //如果自定义业务层定义了自检方法
			return service.CommonCheckRepeatByEditAndTree(ctx, entity, id, data["sName"]) //通用树型结构表添加数据时重复检查方法
		}

		result := system.ReflectUtils{}.DoMethod(customService, "CheckRepeatByEditAndTree", id, data["sName"])
		me := result[0].Interface()

		return me.(*model.MsgEmity)
	}

	//--不是树形数据则使用普通方法检查--//
	if nil == customService { //如果没有自定义业务层
		return service.CommonCheckRepeatByEdit(ctx, entity, id) //通用添加数据时重复检查方法
	}

	method := system.ReflectUtils{}.GetMethod(customService, "CheckRepeatByEdit")
	if !method.IsValid() { //如果自定义业务层定义了自检方法
		return service.CommonCheckRepeatByEdit(ctx, entity, id) //通用添加数据时重复检查方法
	}

	result := system.ReflectUtils{}.DoMethod(customService, "CheckRepeatByEdit", data, id)
	me := result[0].Interface()

	return me.(*model.MsgEmity)
}

/**
 * 通用树型结构表添加数据时重复检查方法
 * dbEntity
 */
func (service CommonService) CommonCheckRepeatByAddAndTree(ctx *gin.Context, dbEntity interface{}) *model.MsgEmity {
	vName := system.ReflectUtils{}.GetFieldValue(dbEntity, model.GtableTreeNodeName)
	if nil == vName {
		return model.MsgEmity{}.Err(1001, "节点名称为空")
	}

	tableInfo := model.TableInfo{}.GetByEntity(dbEntity)

	sName := vName.(string)

	var sPid string
	vPid := system.ReflectUtils{}.GetFieldValue(dbEntity, model.GtablePidKey)
	if nil != vPid {
		sPid = vPid.(string)
	} else {
		sPid = model.TableTreeRootValue
	}

	if sPid == "" {
		sPid = model.TableTreeRootValue
	}

	where := make(map[string]interface{})

	//同一层节点下,展现名不能相同//
	var build strings.Builder
	build.WriteString("SELECT SUM(iCount) AS iCount FROM (")

	if tableInfo.GbHasSign {
		build.WriteString(" 	select SIGN(COUNT(1) * 10) as iCount from ${sDbName}${sTableName}")
		build.WriteString(" 	where ")
		build.WriteString(model.TablesSign)
		build.WriteString(" = @sSign")
		build.WriteString(model.TablesSign)
		build.WriteString(" UNION ALL ")

		where[model.TablesSign] = system.ReflectUtils{}.GetFieldValue(dbEntity, model.GtablesSign)
	}

	build.WriteString(" 	select SIGN(COUNT(1)) as iCount from ${sDbName}${sTableName}")
	build.WriteString(" 	where ${model.TablePidKey} = @sPid and ${model.TableTreeNodeName} = @sName")
	build.WriteString(") TMP")

	txt := build.String()
	txt = strings.Replace(txt, "${sDbName}", gorm.SqlFactory{}.GetDbName(tableInfo.GsDbName), -1)
	txt = strings.Replace(txt, "${sTableName}", tableInfo.GsTableName, -1)
	txt = strings.Replace(txt, "${model.TablePidKey}", model.TablePidKey, -1)
	txt = strings.Replace(txt, "${model.TableTreeNodeName}", model.TableTreeNodeName, -1)

	where[model.TablePidKey] = sPid
	where[model.TableTreeNodeName] = sName

	var iCount int
	dbResult := gorm.SqlFactory{}.Raw(txt, where).Find(&iCount)
	if dbResult.Error != nil {
		Log.Error("查询发生异常:", dbResult.Error)
		return model.MsgEmity{}.Err(1002, "查询数据发生异常:", dbResult.Error)
	}

	if iCount != 0 {
		return model.MsgEmity{}.Err(1003, "节点重复")
	}

	return model.MsgEmity{}.Success(1999, "节点未重复")
}

/**
 * 通用树型结构表添加数据时重复检查方法
 * entity
 */
func (service CommonService) CommonCheckRepeatByEditAndTree(ctx *gin.Context, entity interface{}, id interface{}, sName interface{}) *model.MsgEmity {
	if (nil == sName) || ("" == sName) || ("<nil>" == sName) {
		return model.MsgEmity{}.Err(1001, "节点名称为空")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)

	where := make(map[string]interface{})

	//同一层节点下,展现名不能相同//
	var build strings.Builder
	build.WriteString("SELECT SUM(iCount) AS iCount FROM (")

	if tableInfo.GbHasSign {
		build.WriteString(" 	select SIGN(COUNT(1) * 10) as iCount from ${sDbName}${sTableName}")
		build.WriteString(" 	where ")
		build.WriteString(model.TablesSign)
		build.WriteString(" = @")
		build.WriteString(model.TablesSign)
		build.WriteString(" 	and ${sId} <> @sId")
		build.WriteString(" UNION ALL ")

		where[model.TablesSign] = system.ReflectUtils{}.GetFieldValue(entity, model.GtablesSign)
	}

	build.WriteString(" 	select SIGN(COUNT(1)) as iCount from ${sDbName}${sTableName}")
	build.WriteString(" 	where ${sId} <> @sId")
	build.WriteString(" 	and ${model.TablePidKey} = (select a.${model.TablePidKey} from ${sDbName}${sTableName} a where a.${sId} = @sId)")
	build.WriteString(" 	and ${model.TableTreeNodeName} = #{sName}")
	build.WriteString(") TMP")

	txt := build.String()
	txt = strings.Replace(txt, "${sDbName}", gorm.SqlFactory{}.GetDbName(tableInfo.GsDbName), -1)
	txt = strings.Replace(txt, "${sTableName}", tableInfo.GsTableName, -1)
	txt = strings.Replace(txt, "${sId}", tableInfo.GsKeyName, -1)
	txt = strings.Replace(txt, "${model.TablePidKey}", model.TablePidKey, -1)
	txt = strings.Replace(txt, "${model.TableTreeNodeName}", model.TableTreeNodeName, -1)
	txt = strings.Replace(txt, "#{sName}", "@sName", -1)

	where["sId"] = id
	where["sName"] = sName

	var iCount int
	dbResult := gorm.SqlFactory{}.Raw(txt, where).Find(&iCount)
	if dbResult.Error != nil {
		Log.Error("查询发生异常:", dbResult.Error)
		return model.MsgEmity{}.Err(1002, "查询数据发生异常:", dbResult.Error)
	}

	if iCount != 0 {
		return model.MsgEmity{}.Err(1003, "节点重复")
	}

	return model.MsgEmity{}.Success(1999, "节点未重复")
}

/**
 * 通用添加数据时重复检查方法
 * dbEntity
 */
func (service CommonService) CommonCheckRepeatByAdd(ctx *gin.Context, dbEntity interface{}) *model.MsgEmity {
	tableInfo := model.TableInfo{}.GetByEntity(dbEntity)

	vCheckRepeatCombination := model.GlobalVariable{}.Get(tableInfo.GsTableName + "_CheckRepeatCombination")
	vCheckRepeatAlone := model.GlobalVariable{}.Get(tableInfo.GsTableName + "_CheckRepeatAlone")

	k := 0

	//检查待新增内容是否存在重复数据(多字段组合重复即重复)集合
	if nil != vCheckRepeatCombination {
		checkRepeatCombination := vCheckRepeatCombination.([]string)

		var build strings.Builder
		build.WriteString("SELECT COUNT(1) AS iCount FROM ${sDbName}${sTableName} WHERE 1=1 ")

		var temp strings.Builder
		temp.WriteString("[")

		where := make(map[string]interface{})
		for _, value := range checkRepeatCombination {
			build.WriteString(" AND ")
			build.WriteString(value)
			build.WriteString(" = @")
			build.WriteString(value)

			where[value] = system.ReflectUtils{}.GetFieldValue(dbEntity, "G"+value)
			temp.WriteString("、")
			temp.WriteString(value)
		}

		txt := strings.Replace(build.String(), "1=1 AND ", "", -1)
		txt = strings.Replace(txt, "${sDbName}", gorm.SqlFactory{}.GetDbName(tableInfo.GsDbName), -1)
		txt = strings.Replace(txt, "${sTableName}", tableInfo.GsTableName, -1)

		iCount := 0
		dbResult := gorm.SqlFactory{}.Raw(txt, where).Find(&iCount)
		if dbResult.Error != nil {
			Log.Error("验证数据是否重复发生异常:", dbResult.Error)
			return model.MsgEmity{}.Err(1001, "验证数据是否重复发生异常:", dbResult.Error)
		}

		if iCount != 0 {
			temp.WriteString("]组合发现数据重复")
			return model.MsgEmity{}.Err(1002, strings.Replace(temp.String(), "、", "", 1))
		}

		k++
	}

	//检查待新增内容是否存在重复数据(单独字段重复即重复)集合
	if nil != vCheckRepeatAlone {
		checkRepeatAlone := vCheckRepeatAlone.(map[string]int)

		var build strings.Builder
		build.WriteString("SELECT SUM(iCount) FROM (")

		where := make(map[string]interface{})
		for key, value := range checkRepeatAlone {
			build.WriteString(" union all select (SIGN(COUNT(1)) * ")
			build.WriteString(strconv.Itoa(value))
			build.WriteString(") as iCount ")
			build.WriteString(" from ${sDbName}${sTableName} ")
			build.WriteString(" where ")
			build.WriteString(key)
			build.WriteString("= @")
			build.WriteString(key)

			where[key] = system.ReflectUtils{}.GetFieldValue(dbEntity, "G"+key)
		}

		build.WriteString(") TMP")

		txt := strings.Replace(build.String(), " union all ", " ", 1)
		txt = strings.Replace(txt, "${sDbName}", gorm.SqlFactory{}.GetDbName(tableInfo.GsDbName), -1)
		txt = strings.Replace(txt, "${sTableName}", tableInfo.GsTableName, -1)

		iCount := 0
		dbResult := gorm.SqlFactory{}.Raw(txt, where).Find(&iCount)
		if dbResult.Error != nil {
			Log.Error("验证数据是否重复发生异常:", dbResult.Error)
			return model.MsgEmity{}.Err(1003, "验证数据是否重复发生异常:", dbResult.Error)
		}

		if iCount != 0 {
			var temp strings.Builder
			str := fmt.Sprintf("%0*d", len(checkRepeatAlone), iCount)
			array := []rune(str) //得到字符数组

			ml := len(checkRepeatAlone)
			for key, value := range checkRepeatAlone {
				i := len(strconv.Itoa(value))
				if array[ml-i] == 48 { // ASCII对应: '0' => 48, '1' => 49
					continue
				}

				temp.WriteString("、")
				temp.WriteString(key)
			}

			temp.WriteString("存在重复")

			return model.MsgEmity{}.Err(1004, strings.Replace(temp.String(), "、", "", 1))
		}

		k++
	}

	if 0 == k {
		return model.MsgEmity{}.Success("没有设定验证函数,通过")
	}

	return model.MsgEmity{}.Success("经验证,通过")
}

/**
 * 通用更新数据时重复检查方法
 * entity
 */
func (service CommonService) CommonCheckRepeatByEdit(ctx *gin.Context, entity interface{}, id interface{}) *model.MsgEmity {
	tableInfo := model.TableInfo{}.GetByEntity(entity)

	vCheckRepeatCombination := model.GlobalVariable{}.Get(tableInfo.GsTableName + "_CheckRepeatCombination")
	vCheckRepeatAlone := model.GlobalVariable{}.Get(tableInfo.GsTableName + "_CheckRepeatAlone")

	k := 0

	//检查待修改内容是否存在重复数据(多字段组合重复即重复)集合
	if nil != vCheckRepeatCombination {
		checkRepeatCombination := vCheckRepeatCombination.([]string)

		var build strings.Builder
		build.WriteString("SELECT COUNT(1) AS iCount FROM ${sDbName}${sTableName} WHERE 1=1 ")

		var temp strings.Builder
		temp.WriteString("[")

		where := make(map[string]interface{})
		where[tableInfo.GsKeyName] = id
		build.WriteString(" AND ")
		build.WriteString(tableInfo.GsKeyName)
		build.WriteString(" = @")
		build.WriteString(tableInfo.GsKeyName)

		for _, value := range checkRepeatCombination {
			build.WriteString(" AND ")
			build.WriteString(value)
			build.WriteString(" = @")
			build.WriteString(value)

			where[value] = system.ReflectUtils{}.GetFieldValue(entity, "G"+value)
			temp.WriteString("、")
			temp.WriteString(value)
		}

		txt := strings.Replace(build.String(), "1=1 AND ", "", -1)
		txt = strings.Replace(txt, "${sDbName}", gorm.SqlFactory{}.GetDbName(tableInfo.GsDbName), -1)
		txt = strings.Replace(txt, "${sTableName}", tableInfo.GsTableName, -1)

		iCount := 0
		dbResult := gorm.SqlFactory{}.Raw(txt, where).Find(&iCount)
		if dbResult.Error != nil {
			Log.Error("验证数据是否重复发生异常:", dbResult.Error)
			return model.MsgEmity{}.Err(1001, "验证数据是否重复发生异常:", dbResult.Error)
		}

		if iCount != 0 {
			temp.WriteString("]组合发现数据重复")
			return model.MsgEmity{}.Err(1002, strings.Replace(temp.String(), "、", "", 1))
		}

		k++
	}

	//检查待修改内容是否存在重复数据(单独字段重复即重复)集合
	if nil != vCheckRepeatAlone {
		checkRepeatAlone := vCheckRepeatAlone.(map[string]int)

		var build strings.Builder
		build.WriteString("SELECT SUM(iCount) FROM (")

		where := make(map[string]interface{})
		where[tableInfo.GsKeyName] = id

		for key, value := range checkRepeatAlone {
			build.WriteString(" union all select (SIGN(COUNT(1)) * ")
			build.WriteString(strconv.Itoa(value))
			build.WriteString(") as iCount ")
			build.WriteString(" from ${sDbName}${sTableName} ")
			build.WriteString(" where ")
			build.WriteString(key)
			build.WriteString("= @")
			build.WriteString(key)
			build.WriteString(" and ")
			build.WriteString(tableInfo.GsKeyName)
			build.WriteString(" = @")
			build.WriteString(tableInfo.GsKeyName)

			where[key] = system.ReflectUtils{}.GetFieldValue(entity, "G"+key)
		}

		build.WriteString(") TMP")

		txt := strings.Replace(build.String(), " union all ", " ", 1)
		txt = strings.Replace(txt, "${sDbName}", gorm.SqlFactory{}.GetDbName(tableInfo.GsDbName), -1)
		txt = strings.Replace(txt, "${sTableName}", tableInfo.GsTableName, -1)

		iCount := 0
		dbResult := gorm.SqlFactory{}.Raw(txt, where).Find(&iCount)
		if dbResult.Error != nil {
			Log.Error("验证数据是否重复发生异常:", dbResult.Error)
			return model.MsgEmity{}.Err(1003, "验证数据是否重复发生异常:", dbResult.Error)
		}

		if iCount != 0 {
			var temp strings.Builder
			str := fmt.Sprintf("%0*d", len(checkRepeatAlone), iCount)
			array := []rune(str) //得到字符数组

			ml := len(checkRepeatAlone)
			for key, value := range checkRepeatAlone {
				i := len(strconv.Itoa(value))
				if array[ml-i] == 48 { // ASCII对应: '0' => 48, '1' => 49
					continue
				}

				temp.WriteString("、")
				temp.WriteString(key)
			}

			temp.WriteString("存在重复")

			return model.MsgEmity{}.Err(1004, strings.Replace(temp.String(), "、", "", 1))
		}

		k++
	}

	if 0 == k {
		return model.MsgEmity{}.Success("没有设定验证函数,通过")
	}

	return model.MsgEmity{}.Success("经验证,通过")
}

/**
 * 读取树形结构数据
 * @param entity
 * @param sGroupColumn
 * @param sGroupName
 * @return
 */
func (service CommonService) FindByTree(ctx *gin.Context, entity interface{}, sGroupColumn, sGroupName string) *model.MsgEmity {
	tableInfo := model.TableInfo{}.GetByEntity(entity)
	if !tableInfo.GbHasPid {
		return model.MsgEmity{}.Err(1001, "指定分组字段不存在！")
	}

	//-- 从文件读取 --//
	var filePath string

	if sGroupName == "" {
		filePath = "./temp/cache/" + tableInfo.GsTableName + "/tree.txt"
	} else {
		filePath = "./temp/cache/" + tableInfo.GsTableName + "/Group_" + sGroupName + ".txt"
	}

	me := data.JsonUtil{}.FormFile(filePath, map[string]interface{}{})
	if me.Gsuccess {
		return model.MsgEmity{}.Success(me.Gdata, "在文件中找到") //返回结果
	}

	//-- 从数据库读取 --//
	var build strings.Builder
	build.WriteString("SELECT * FROM ${sDbName}${sTableName} WHERE ")
	build.WriteString(model.TableMajorKeyString)
	build.WriteString(" > 0")

	where := []interface{}{}
	if "" != sGroupName {
		build.WriteString(" AND ")
		build.WriteString(model.TablePathKey)
		build.WriteString(" LIKE (")
		build.WriteString(" 	select CONCAT(a.")
		build.WriteString(model.TablePathKey)
		build.WriteString(", '%')")
		build.WriteString(" 	from ${sDbName}${sTableName} a")

		if "" != sGroupColumn {
			build.WriteString(" 	where a.")
			build.WriteString(sGroupColumn) //指定字段作为分组标识
			build.WriteString(" = ?")
		} else if tableInfo.GbHasOnlyign { //启用唯一标识作为关键字
			build.WriteString(" 	where a.")
			build.WriteString(model.TableOnlyignName) //启用唯一标识作为关键字
			build.WriteString(" = ?")                 //启用唯一标识作为关键字
		} else {
			build.WriteString(" 	where a.")
			build.WriteString(model.TableTreeNodeName)
			build.WriteString(" = ?")
		}

		build.WriteString(" )")
		where = append(where, sGroupName)
	}

	build.WriteString(" ORDER BY ")
	build.WriteString(model.TablePathKey)

	txt := strings.Replace(build.String(), "${sDbName}", gorm.SqlFactory{}.GetDbName(tableInfo.GsDbName), -1)
	txt = strings.Replace(txt, "${sTableName}", tableInfo.GsTableName, -1)
	rows, err := gorm.SqlFactory{}.Raw(txt, where).Rows()
	defer rows.Close()

	if nil != err {
		Log.Error("查询发生异常:", err)
		return model.MsgEmity{}.Err(1002, "查询发生异常:", err)
	}

	res := gorm.SqlFactory{}.ScanRows2mapI(rows)
	if res == nil {
		return model.MsgEmity{}.Err(1003, "查询后数据转换发生异常")
	}

	if len(res) < 1 {
		return model.MsgEmity{}.Err(1004, "数据为空")
	}

	sRootValue := model.TableTreeRootValue
	if sGroupName != "" {
		sRootValue = res[0][model.TableMajorKeyString].(string) //分组查询情况下必须要一个根节点(因为已经path排序)
	}

	me = CommonService{}.CreateTree(res, sRootValue, model.TableMajorKeyString, model.TablePidKey, "childs")
	if !me.Gsuccess {
		return me
	}

	if len((me.Gdata).([]interface{})) < 1 {
		return model.MsgEmity{}.Err(1005, "数据转换后构造树型数据为空")
	}

	data.JsonUtil{}.ToFile(me.Gdata, filePath) //保存到文件

	return model.MsgEmity{}.Success(me.Gdata, "查询成功")
}

/**
 * List转树形结构
 * @param source Map或切片结构
 * @param rootName
 * @param idFieldName
 * @param pIdFieldName
 * @param childFieldName
 * @return
 */
func (this CommonService) CreateTree(source interface{},
	rootName, idFieldName, pIdFieldName, childFieldName string) *model.MsgEmity {
	if nil == source {
		return model.MsgEmity{}.Err(5001, "没有数据无法进行树结构创建!")
	}

	if "" == strings.TrimSpace(idFieldName) {
		return model.MsgEmity{}.Err(5002, "对象字段中的编号属性名称必须提供!")
	}

	if "" == strings.TrimSpace(pIdFieldName) {
		return model.MsgEmity{}.Err(5003, "对象字段中的上级编号属性名称必须提供!")
	}

	if "" == strings.TrimSpace(childFieldName) {
		return model.MsgEmity{}.Err(5004, "对象字段中的子节点集合属性名称必须提供!")
	}

	sourceTypeName := reflect.TypeOf(source).String()
	if strings.HasPrefix(sourceTypeName, "[]map[string]interface") {
		return this.createTreeByMap(source.([]map[string]interface{}), rootName, idFieldName, pIdFieldName, childFieldName)
	}

	return this.createTreeByList(source.([]interface{}), rootName, idFieldName, pIdFieldName, childFieldName)
}

/**
 * List转树形结构
 * @param source 切片结构
 * @param rootName
 * @param idFieldName
 * @param pIdFieldName
 * @param childFieldName
 * @return
 */
func (service CommonService) createTreeByList(source []interface{},
	rootName, idFieldName, pIdFieldName, childFieldName string) *model.MsgEmity {
	if nil == source || (len(source) < 1) {
		return model.MsgEmity{}.Err(5001, "没有数据无法进行树结构创建!")
	}

	result := []interface{}{}

	rt := reflect.TypeOf(source[0])
	sourceTypeName := rt.String()

	isMap := strings.HasPrefix(sourceTypeName, "map[string]interface") //如果数据类型是Map则取值不能用反射方式

	if "" == strings.TrimSpace(rootName) {
		rootName = model.TableTreeRootValue //未指定就默认为'00'做根节点
	}

	//-- 将所有数据进行预分组存储,同时筛选出根节点 --//
	groupMap := map[string][]interface{}{} //待进行挂接的子分组
	allMap := map[string]interface{}{}
	for _, object := range source {
		sGroupName := ""
		if !isMap {
			sGroupName = system.ReflectUtils{}.GetFieldValue(object, pIdFieldName).(string)
		} else {
			sGroupName = (object.(map[string]interface{}))[pIdFieldName].(string)
		}

		if "" == strings.TrimSpace(sGroupName) {
			sGroupName = rootName //如果父节点信息为空,则默认为根节点
		}

		sGroupName = strings.TrimSpace(sGroupName) //所在组名

		sid := ""
		if isMap {
			sid = (object.(map[string]interface{}))[idFieldName].(string)
		} else {
			sid = (system.ReflectUtils{}.GetFieldValue(object, idFieldName)).(string)
		}

		allMap[sid] = object

		if rootName == sGroupName {
			result = append(result, object) //加入根节点列表
			continue
		}

		childs, ok := groupMap[sGroupName]
		if !ok {
			childs = []interface{}{}
			groupMap[sGroupName] = childs
		}

		childs = append(childs, object)
		groupMap[sGroupName] = childs
	}

	//--将所有分组寻找父节点--//
	for key, value := range groupMap {
		obj := allMap[key]
		if nil == obj {
			continue
		}

		sTypeName := reflect.TypeOf(obj).String()
		if strings.HasPrefix(sTypeName, "map[string]interface") {
			(obj.(map[string]interface{}))[childFieldName] = value
			continue
		}

		system.ReflectUtils{}.SetFieldValue(obj, childFieldName, value) // 设置子节点集合
	}

	return model.MsgEmity{}.Success(result, "构造成功!")
}

/**
 * List转树形结构
 * @param source Map结构
 * @param rootName
 * @param idFieldName
 * @param pIdFieldName
 * @param childFieldName
 * @return
 */
func (service CommonService) createTreeByMap(source []map[string]interface{},
	rootName, idFieldName, pIdFieldName, childFieldName string) *model.MsgEmity {
	if nil == source || (len(source) < 1) {
		return model.MsgEmity{}.Err(5001, "没有数据无法进行树结构创建!")
	}

	result := []interface{}{}

	rt := reflect.TypeOf(source[0])
	sourceTypeName := rt.String()

	isMap := strings.HasPrefix(sourceTypeName, "map[string]interface") //如果数据类型是Map则取值不能用反射方式

	if "" == strings.TrimSpace(rootName) {
		rootName = model.TableTreeRootValue //未指定就默认为'00'做根节点
	}

	//-- 将所有数据进行预分组存储,同时筛选出根节点 --//
	groupMap := map[string][]interface{}{} //待进行挂接的子分组
	allMap := map[string]interface{}{}
	for _, object := range source {
		sGroupName := ""
		if !isMap {
			sGroupName = system.ReflectUtils{}.GetFieldValue(object, pIdFieldName).(string)
		} else {
			sGroupName = object[pIdFieldName].(string)
		}

		if "" == strings.TrimSpace(sGroupName) {
			sGroupName = rootName //如果父节点信息为空,则默认为根节点
		}

		sGroupName = strings.TrimSpace(sGroupName) //所在组名

		sid := ""
		if isMap {
			sid = object[idFieldName].(string)
		} else {
			sid = (system.ReflectUtils{}.GetFieldValue(object, idFieldName)).(string)
		}

		allMap[sid] = object

		if rootName == sGroupName {
			result = append(result, object) //加入根节点列表
			continue
		}

		childs, ok := groupMap[sGroupName]
		if !ok {
			childs = []interface{}{}
			groupMap[sGroupName] = childs
		}

		childs = append(childs, object)
		groupMap[sGroupName] = childs
	}

	//--将所有分组寻找父节点--//
	for key, value := range groupMap {
		obj := allMap[key]
		if nil == obj {
			continue
		}

		sTypeName := reflect.TypeOf(obj).String()
		if strings.HasPrefix(sTypeName, "map[string]interface") {
			(obj.(map[string]interface{}))[childFieldName] = value
			continue
		}

		system.ReflectUtils{}.SetFieldValue(obj, childFieldName, value) // 设置子节点集合
	}

	return model.MsgEmity{}.Success(result, "构造成功!")
}

/**
 * 根据字段名取指定记录编号的数据库表中对应字段的值
 * @param entity 实体类
 * @param id
 * @param fieldNames 待取数据的字段名称集合
 * @return model.MsgEmity 返回内容data中存放的是Map
 */
func (service CommonService) GetValueByFieldName(ctx *gin.Context, entity interface{}, id interface{}, fieldNames []string) *model.MsgEmity {
	fieldNames = system.ReflectUtils{}.HoldByEntityToArray(entity, fieldNames, "", "G") //按实体保留数组中的数据
	if len(fieldNames) < 1 {
		return model.MsgEmity{}.Err(7001, "没有对应的数据可查询！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)

	var build strings.Builder
	build.WriteString("SELECT ")

	for _, val := range fieldNames {
		build.WriteString(",")
		build.WriteString(val)
	}

	build.WriteString(" FROM ")
	build.WriteString(gorm.SqlFactory{}.GetDbName(tableInfo.GsDbName))
	build.WriteString(tableInfo.GsTableName)
	build.WriteString(" WHERE ")
	build.WriteString(tableInfo.GsKeyName)
	build.WriteString("=@")
	build.WriteString(tableInfo.GsKeyName)

	where := make(map[string]interface{})
	where[tableInfo.GsKeyName] = id

	if (!ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5)) { //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除
		build.WriteString(" AND ")
		build.WriteString(model.TableCreatorName)
		build.WriteString("=@")
		build.WriteString(model.TableCreatorName)
		where[model.TableCreatorName] = ModuleUtil{}.CurrentLoginUserId(ctx)
	}

	sql := strings.Replace(build.String(), ",", "", 1)
	rows, err := gorm.SqlFactory{}.Raw(sql, where).Rows()

	defer rows.Close()

	if nil != err {
		Log.Error("查询发生异常:", err)
		return model.MsgEmity{}.Err(7002, "查询发生异常:", err)
	}

	res := gorm.SqlFactory{}.ScanRows2mapI(rows)
	if res == nil {
		Log.Error("查询发生异常:", err)
		return model.MsgEmity{}.Err(7003, "查询发生异常:", err)
	}

	if len(res) < 1 {
		return model.MsgEmity{}.Err(7004, "数据不存在！")
	}

	return model.MsgEmity{}.Success(res[0], "查询成功")
}

/**
 * 根据字段名取指定记录编号的数据库表中对应字段的值
 * @param entity 实体类
 * @param id
 * @param fieldName 待取数据的字段名称集合
 * @return model.MsgEmity 返回内容data中存放的是Map
 */
func (service CommonService) GetValueByField(ctx *gin.Context, entity interface{}, id interface{}, fieldName string) *model.MsgEmity {
	fieldName = strings.TrimSpace(fieldName)
	if "" == fieldName {
		return model.MsgEmity{}.Err(7001, "没有对应的数据可查询！")
	}

	if (!system.ReflectUtils{}.HasField(entity, fieldName)) {
		return model.MsgEmity{}.Err(7002, "指定字段不存在！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)

	var build strings.Builder
	build.WriteString("SELECT ")
	build.WriteString(fieldName)
	build.WriteString(" FROM ")
	build.WriteString(gorm.SqlFactory{}.GetDbName(tableInfo.GsDbName))
	build.WriteString(tableInfo.GsTableName)
	build.WriteString(" WHERE ")
	build.WriteString(tableInfo.GsKeyName)
	build.WriteString("=@")
	build.WriteString(tableInfo.GsKeyName)

	where := make(map[string]interface{})
	where[tableInfo.GsKeyName] = id

	if (!ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5)) { //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除
		build.WriteString(" AND ")
		build.WriteString(model.TableCreatorName)
		build.WriteString("=@")
		build.WriteString(model.TableCreatorName)
		where[model.TableCreatorName] = ModuleUtil{}.CurrentLoginUserId(ctx)
	}

	sql := strings.Replace(build.String(), ",", "", 1)
	rows, err := gorm.SqlFactory{}.Raw(sql, where).Rows()

	defer rows.Close()

	if nil != err {
		Log.Error("查询发生异常:", err)
		return model.MsgEmity{}.Err(7003, "查询发生异常:", err)
	}

	res := gorm.SqlFactory{}.ScanRows2mapI(rows)
	if res == nil {
		Log.Error("查询发生异常:", err)
		return model.MsgEmity{}.Err(7004, "查询发生异常:", err)
	}

	if len(res) < 1 {
		return model.MsgEmity{}.Err(7005, "数据不存在！")
	}

	return model.MsgEmity{}.Success(res[0], "查询成功")
}

/**
 * 取记录对应的版本号
 * @param entity 实体类
 * @param idName 编号
 * @return
 */
func (service CommonService) GetiVersion(ctx *gin.Context, entity interface{}, id interface{}) *model.MsgEmity {
	if "" == fmt.Sprintf("%v", id) {
		return model.MsgEmity{}.Err(8001, "记录编号参数为空！")
	}

	return CommonDao{}.GetiVersion(entity, id)
}

/**
 * 取记录对应的状态值
 * @param entity 实体类
 * @param idName 编号
 * @return
 */
func (service CommonService) GetiState(ctx *gin.Context, entity interface{}, id interface{}) *model.MsgEmity {
	if "" == fmt.Sprintf("%v", id) {
		return model.MsgEmity{}.Err(8001, "记录编号参数为空！")
	}

	return CommonDao{}.GetiState(entity, id)
}

/**
 * 根据关键值取对象集合
 * @Param entity 实体类
 * @Param where 存放查询条件
 * @return model.MsgEmity
 */
func (service CommonService) FindByKey(ctx *gin.Context, entity interface{}, where map[string]interface{}) *model.MsgEmity {
	where = system.ReflectUtils{}.HoldByEntity(entity, where, "", "G") //按实体保留map中的数据
	if len(where) < 1 {
		return model.MsgEmity{}.Err(7001, "没有对应的查询条件！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.FindByKey(entity, where, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

/**
 * 根据关键值取对象集合中的第一个
 * @Param entity 实体类
 * @Param where 存放查询条件
 * @param fields 指定要查询的字段集合
 * @return model.MsgEmity
 */
func (service CommonService) FindOneByKey(ctx *gin.Context, entity interface{}, where map[string]interface{}, fields ...string) *model.MsgEmity {
	where = system.ReflectUtils{}.HoldByEntity(entity, where, "", "G") //按实体保留map中的数据
	if len(where) < 1 {
		return model.MsgEmity{}.Err(8001, "没有对应的查询条件！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.FindOneByKey(entity, where, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator, fields...)
}

/**
 * 根据关键值取对象集合中的符合条件的第一条记录的指定字段
 * @Param entity 实体类
 * @Param where 存放查询条件
 * @param fieldName 指定要查询的字段
 * @return model.MsgEmity
 */
func (service CommonService) FindValueByKey(ctx *gin.Context, entity interface{}, where map[string]interface{}, fieldName string) *model.MsgEmity {
	where = system.ReflectUtils{}.HoldByEntity(entity, where, "", "G") //按实体保留map中的数据
	if len(where) < 1 {
		return model.MsgEmity{}.Err(8001, "没有对应的查询条件！")
	}

	fieldName = strings.TrimSpace(fieldName)
	if "" == fieldName {
		return model.MsgEmity{}.Err(8002, "没有待查字段！")
	}

	if (!system.ReflectUtils{}.HasField(entity, fieldName)) {
		return model.MsgEmity{}.Err(8003, "指定字段不存在！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.FindValueByKey(entity, where, fieldName, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

/**
 * 根据指定字段进行分组查询
 * @Param entity 实体类
 * @Param where 存放查询条件
 * @param fieldMap 指定要查询的字段集合(原字段, 别名)
 * @return model.MsgEmity
 */
func (service CommonService) FindByFields(ctx *gin.Context, entity interface{}, where map[string]interface{}, fieldMap map[string]string) *model.MsgEmity {
	where = system.ReflectUtils{}.HoldByEntity(entity, where, "", "G") //按实体保留map中的数据

	if nil == fieldMap || len(fieldMap) < 1 {
		return model.MsgEmity{}.Err(8002, "没有待查字段！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.FindByFields(entity, where, fieldMap, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

/**
 * 根据关键值查数量
 * @Param entity 实体类
 * @Param where 存放查询条件
 * @return model.MsgEmity
 */
func (service CommonService) FindCountByKey(ctx *gin.Context, entity interface{}, where map[string]interface{}) *model.MsgEmity {
	where = system.ReflectUtils{}.HoldByEntity(entity, where, "", "G") //按实体保留map中的数据

	if len(where) < 1 {
		return model.MsgEmity{}.Err(7001, "没有对应的查询条件！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.FindCountByKey(entity, where, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

// /**
//  * 以事务方式执行Mapper下的多个方法
//  * 注意:Mapper必须存在才能执行
//  * @param mapper iBatis实体
//  * @Param funcInfo 接口信息集合(以3对为一组) <函数名, 函数参数类型集合, 函数参数集合, 函数名, 函数参数类型集合, 函数参数集合....>
//  * @return model.MsgEmity 返回对象数组(各函数执行结果)
//  */
// func (service CommonService) transactionMapping(Object mapper, Object...funcInfo) *model.MsgEmity {

// 	return model.MsgEmity{}.Success(res, "查询成功")
// }

/**
 * 根据字段名取分组数据
 * @param entity 实体类
 * @param sCreator 指定用户
 * @param fields 字段名与别名对象
 * @return
 */
func (service CommonService) GroupByField(ctx *gin.Context, entity interface{}, sCreator string, fields map[string]string) *model.MsgEmity {
	if len(fields) < 1 {
		return model.MsgEmity{}.Err(8001, "没有对应的待查字段！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.GroupByField(entity, sCreator, fields, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

/**
 * 根据字段名取分组数据及分组后数量
 * @param entity 实体类
 * @param sCreator 指定用户
 * @param fields 字段名与别名对象
 * @return
 */
func (service CommonService) GroupByFieldAndCount(ctx *gin.Context, entity interface{}, sCreator string, fields map[string]string) *model.MsgEmity {
	if len(fields) < 1 {
		return model.MsgEmity{}.Err(8001, "没有对应的待查字段！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.GroupByFieldAndCount(entity, sCreator, fields, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

/**
 * 取表中指定字段的最大值
 * @param entity 实体类
 * @param sCreator 指定用户
 * @param field 字段名
 * @param where 查询条件字符串
 * @return model.MsgEmity
 */
func (service CommonService) MaxByField(ctx *gin.Context, entity interface{}, sCreator string, field string, where map[string]interface{}) *model.MsgEmity {
	field = strings.TrimSpace(field)
	if "" == field {
		return model.MsgEmity{}.Err(7001, "没有待查字段！")
	}

	if len(where) < 1 {
		return model.MsgEmity{}.Err(7002, "没有对应的查询条件！")
	}

	if (!system.ReflectUtils{}.HasField(entity, field)) {
		return model.MsgEmity{}.Err(7003, "指定字段不存在！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.MaxByField(entity, sCreator, field, where, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

/**
 * 取表中指定字段的最小值
 * @param entity 实体类
 * @param sCreator 指定用户
 * @param field 字段名
 * @param where 查询条件
 * @return model.MsgEmity
 */
func (service CommonService) MinByField(ctx *gin.Context, entity interface{}, sCreator string, field string, where map[string]interface{}) *model.MsgEmity {
	field = strings.TrimSpace(field)
	if "" == field {
		return model.MsgEmity{}.Err(7001, "没有待查字段！")
	}

	if len(where) < 1 {
		return model.MsgEmity{}.Err(7002, "没有对应的查询条件！")
	}

	if (!system.ReflectUtils{}.HasField(entity, field)) {
		return model.MsgEmity{}.Err(7003, "指定字段不存在！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.MinByField(entity, sCreator, field, where, ModuleUtil{}.CurrentLoginUserId(ctx), onlyCreator)
}

/**
 * 检查关键值记录是否存在(返回1:存在;0:不存在)
 * @param entity 实体类
 * @Param id
 * @return model.MsgEmity
 */
func (service CommonService) HasById(ctx *gin.Context, entity interface{}, id interface{}) *model.MsgEmity {
	if "" == fmt.Sprintf("%v", id) {
		return model.MsgEmity{}.Err(8001, "记录编号参数为空！")
	}

	return CommonDao{}.HasById(entity, id)
}

/**
 * 检查关键值记录是否存在(返回1:存在;0:不存在)
 * @param entity 实体类
 * @Param keyName 字段名
 * @Param keyValue 字段值
 * @return model.MsgEmity
 */
func (service CommonService) HasByKey(ctx *gin.Context, entity interface{}, keyName string, keyValue interface{}) *model.MsgEmity {
	keyName = strings.TrimSpace(keyName)
	if "" == keyName {
		return model.MsgEmity{}.Err(7001, "字段名参数为空！")
	}

	if (nil == keyValue) || ("" == fmt.Sprintf("%v", keyValue)) || ("<nil>" == fmt.Sprintf("%v", keyValue)) {
		return model.MsgEmity{}.Err(7002, "字段值参数为空！")
	}

	if (!system.ReflectUtils{}.HasField(entity, keyName)) {
		return model.MsgEmity{}.Err(7003, "指定字段不存在！")
	}

	dataInfo := model.DataInfo{}.GetDataInfoByName(entity, keyName)
	if nil == dataInfo {
		return model.MsgEmity{}.Err(7004, "字段备注信息缺失")
	}

	switch dataInfo.GsDbFileType {
	case "int":
		temp, err := strconv.Atoi(keyValue.(string))
		if err != nil {
			return model.MsgEmity{}.Err(7005, "字段值参数为不符合规范！")
		}
		keyValue = temp
	case "bigint":
		temp, err := strconv.ParseInt(keyValue.(string), 10, 64)
		if err != nil {
			return model.MsgEmity{}.Err(7006, "字段值参数为不符合规范！")
		}
		keyValue = temp
	}

	return CommonDao{}.HasByKey(entity, keyName, keyValue)
}

/**
 * 清理指定用户的缓存
 * @param cacheName 缓存名
 * @Param sUser 用户名
 * @return model.MsgEmity
 */
func (service CommonService) ClearCache(ctx *gin.Context, cacheName string, sUser string) *model.MsgEmity {
	cacheName = strings.TrimSpace(cacheName)
	if "" == cacheName {
		return model.MsgEmity{}.Err(7001, "指定'缓存库名称'参数为空！")
	}

	sUser = strings.TrimSpace(sUser)
	if "" == sUser {
		cacheName = cacheName + sUser
	}

	if (model.GlobalVariable{}.Del(cacheName)) {
		return model.MsgEmity{}.Success(7999, "清理成功！")
	}

	return model.MsgEmity{}.Err(7002, "清理失败！")
}

/**
 * 查询组结构数据
 * @param r Http请求对象
 * @param entity 实体类
 * @param sGroupColumn 分组名(树节点)所在字段名
 * @param sGroupName 分组名(树节点)
 * @return
 */
func (service CommonService) FindByGroup(ctx *gin.Context, entity interface{}, sGroupColumn, sGroupName string) *model.MsgEmity {
	return service.FindByTree(ctx, entity, sGroupColumn, sGroupName)
}

/**
 * 添加数据到指定组下
 * 警告:对象必须符合树形结构要求,如:sId、sPid
 * @param r Http请求对象
 * @param sGroupName 分组字段名称(树节点)
 * @param sGroupValue 分组字段值(树节点)
 * @param entity 实体对象
 * @return
 */
func (service CommonService) AddToGroup(ctx *gin.Context, entity interface{}, sGroupName, sGroupValue string) *model.MsgEmity {
	if sGroupName == "" {
		return model.MsgEmity{}.Err(8001, "节点参数不能为空!")
	}

	if nil == entity {
		return model.MsgEmity{}.Err(8002, "实体对象不能为空!")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)
	if !tableInfo.GbHasPid {
		return model.MsgEmity{}.Err(1001, "指定分组字段不存在！")
	}

	if model.TableMajorKeyString != tableInfo.GsKeyName {
		return model.MsgEmity{}.Err(8003, "实体类型没有sId字段,不符合格式要求!")
	}

	if !tableInfo.GbHasPid {
		return model.MsgEmity{}.Err(8004, "实体类型没有sPid字段,不符合格式要求!")
	}

	//-- 查组所在记录编号 --//
	var build strings.Builder
	build.WriteString("SELECT ")
	build.WriteString(model.TableMajorKeyString)
	build.WriteString(" FROM ")
	build.WriteString(gorm.SqlFactory{}.GetDbName(tableInfo.GsDbName))
	build.WriteString(tableInfo.GsTableName)
	build.WriteString(" WHERE ")
	build.WriteString(sGroupName)
	build.WriteString("=? LIMIT 0, 1")

	sPId := ""
	dbResult := gorm.SqlFactory{}.Raw(build.String(), sGroupValue).Find(&sPId)
	if dbResult.Error != nil {
		Log.Error("查询发生异常:", dbResult.Error)
		return model.MsgEmity{}.Err(8005, "查询发生异常:", dbResult.Error)
	}

	if sPId == "" {
		return model.MsgEmity{}.Err(8006, "指定组不存在,不能用此方法添加!")
	}

	system.ReflectUtils{}.SetFieldValue(entity, model.TablePidKey, sPId) // 父编号就是查出来的数据

	model.DataInfo{}.SetDataInfoDefault(entity) //对对象中添加了dataInfo注解的属性添加默认值

	me := service.SupplyDbEntityAttrByAdd(ctx, entity, "", "")
	if !me.Gsuccess {
		return me.IncCode(7030)
	}

	me = model.DataInfo{}.ValidAttrByAdd(entity, []string{}) //对对象中添加了model.DataInfo注解的属性检查限制
	if !me.Gsuccess {
		return me.IncCode(7020)
	}

	me = service.ValidEntityRepeatByAdd(ctx, entity) //验证新增数据是否存在重复
	if !me.Gsuccess {
		return me.IncCode(7030)
	}

	return CommonDao{}.AddCommon(entity)
}

/**
 * 执行SQL脚本获取单行单列数据
 * 注意:库名必须用${}进行包装,此脚本应只存在一条记录且为单列
 * @param sql 待执行的SQL脚本
 * @return model.MsgEmity
 */
func (service CommonService) DoSql(sql string) *model.MsgEmity {
	return CommonDao{}.DoSql(sql)
}

/**
 * 执行SQL脚本获取单行单列数据
 * 注意:库名必须用${}进行包装,此脚本应只存在一条记录且为单列
 * @param sql 待执行的SQL脚本
 * @return model.MsgEmity
 */
func (service CommonService) ExecSql(sql string) *model.MsgEmity {
	return CommonDao{}.ExecSql(sql)
}

/**
 * 执行SQL脚本获取单行单列数据
 * 注意:库名必须用${}进行包装,此脚本应只存在一条记录且为单列
 * @param sql 待执行的SQL脚本
 * @return model.MsgEmity
 */
func (service CommonService) GetValue(sql string) *model.MsgEmity {
	return CommonDao{}.GetValue(sql)
}

/**
 * 执行SQL脚本获取一行数据(多列)
 * 注意:库名必须用${}进行包装,此脚本应只存在一条记录
 * @param sql 待执行的SQL脚本
 * @return model.MsgEmity
 */
func (service CommonService) GetRow(sql string) *model.MsgEmity {
	return CommonDao{}.GetRow(sql)
}

/**
 * 执行SQL脚本获取多行数据(多列)
 * 注意:库名必须用${}进行包装,此脚本可返回多条记录
 * @param sql SQL脚本
 * @return model.MsgEmity
 */
func (service CommonService) GetRows(sql string) *model.MsgEmity {
	return CommonDao{}.GetRows(sql)
}

/**
 * 根据关键值翻转值(限布尔值类型,1转2,2转1)
 * 警告:此方法只支持布尔值类型,且只支持翻转1和2
 * @Param ctx http请求对象
 * @Param entity 实体类
 * @Param where 存放查询条件
 * @Param reversalColumn 翻转的字段名
 * @return model.MsgEmity
 */
func (service CommonService) ReversalByKey(ctx *gin.Context, entity interface{}, where map[string]interface{}, reversalColumn string) *model.MsgEmity {
	currentUser := ModuleUtil{}.CurrentLoginUserId(ctx)
	tableInfo := model.TableInfo{}.GetByEntity(entity)
	onlyCreator := !ModuleUtil{}.EnableTag(tableInfo.GsTableName, 6) //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除

	return CommonDao{}.ReversalByKey(entity, where, reversalColumn, currentUser, onlyCreator)
}

/**
 * 根据条件仅查询指定字段名数据
 * @param entity 实体类
 * @param where
 * @param fieldNames 待取数据的字段名称集合
 * @return model.MsgEmity 返回内容data中存放的是Map
 */
func (service CommonService) FindField(ctx *gin.Context, entity interface{}, where map[string]interface{}, fieldNames []string) *model.MsgEmity {
	fieldNames = system.ReflectUtils{}.HoldByEntityToArray(entity, fieldNames, "", "G") //按实体保留数组中的数据
	if len(fieldNames) < 1 {
		return model.MsgEmity{}.Err(7001, "没有对应的数据可查询！")
	}

	tableInfo := model.TableInfo{}.GetByEntity(entity)

	var build strings.Builder
	build.WriteString("SELECT ")

	for _, val := range fieldNames {
		build.WriteString(",")
		build.WriteString(val)
	}

	build.WriteString(" FROM ")
	build.WriteString(gorm.SqlFactory{}.GetDbName(tableInfo.GsDbName))
	build.WriteString(tableInfo.GsTableName)
	build.WriteString(" WHERE 1=1")

	for k, _ := range where {
		build.WriteString(" AND ")
		build.WriteString(k)
		build.WriteString("=@")
		build.WriteString(k)
	}

	if (!ModuleUtil{}.EnableTag(tableInfo.GsTableName, 5)) { //7个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆、物理删除
		build.WriteString(" AND ")
		build.WriteString(model.TableCreatorName)
		build.WriteString("=@")
		build.WriteString(model.TableCreatorName)
		where[model.TableCreatorName] = ModuleUtil{}.CurrentLoginUserId(ctx)
	}

	sql := strings.Replace(build.String(), ",", "", 1)
	sql = strings.Replace(sql, " WHERE 1=1 AND ", " WHERE ", -1)

	rows, err := gorm.SqlFactory{}.Raw(sql, where).Rows()

	defer rows.Close()

	if nil != err {
		Log.Error("查询发生异常:", err)
		return model.MsgEmity{}.Err(7002, "查询发生异常:", err)
	}

	res := gorm.SqlFactory{}.ScanRows2mapI(rows)
	if res == nil {
		Log.Error("查询发生异常:", err)
		return model.MsgEmity{}.Err(7003, "查询发生异常:", err)
	}

	if len(res) < 1 {
		return model.MsgEmity{}.Err(7004, "数据不存在！")
	}

	return model.MsgEmity{}.Success(res[0], "查询成功")
}

/**
 * 上传文件
 * @param ctx http请求对象
 * @param modelName 模块名称
 * @return model.MsgEmity
 */
func (service CommonService) UpFile(ctx *gin.Context, modelName string) *model.MsgEmity {
	if upFilePath == "" {
		upFilePath = AppUtil{}.ReadConfigKey("App", "UpFilePath", "./data/app/").(string)
		if !strings.HasSuffix(upFilePath, "/") {
			upFilePath = upFilePath + "/"
		}
	}

	// 指定上传目录
	targetDir := upFilePath + modelName
	// 确保目录存在
	if err := os.MkdirAll(targetDir, 0755); err != nil {
		return model.MsgEmity{}.Err(8001, "无法创建目录！")
	}

	// 单个文件上传示例
	file, err := ctx.FormFile("file")
	if err != nil {
		return model.MsgEmity{}.Err(8002, "'file'参数缺失！")
	}

	// 读取文件
	src, err := file.Open()
	if err != nil {
		return model.MsgEmity{}.Err(8003, "无法打开上传的文件！")
	}

	defer src.Close()

	sFilename := data.UUIDUtil{}.Get()
	// 保存文件到指定目录
	dst, err := os.Create(filepath.Join(targetDir, sFilename))
	if err != nil {
		return model.MsgEmity{}.Err(8004, "无法保存文件！")
	}
	defer dst.Close()

	_, err = dst.ReadFrom(src)
	if err != nil {
		return model.MsgEmity{}.Err(8005, "保存文件内容失败！")
	}

	return model.MsgEmity{}.Success(sFilename, "上传成功！")
}

/**
 * 获取图片
 * @param ctx http请求对象
 * @param modelName 模块名称
 * @param filename 文件名
 */
func (service CommonService) LookImg(ctx *gin.Context, modelName, filename string) {
	if upFilePath == "" {
		upFilePath = AppUtil{}.ReadConfigKey("App", "UpFilePath", "./data/app/").(string)
		if !strings.HasSuffix(upFilePath, "/") {
			upFilePath = upFilePath + "/"
		}
	}

	filePath := upFilePath + modelName + "/" + filename // 假设文件存储在 ./texts 目录下

	// 读取图片文件
	content, err := os.ReadFile(filePath)
	if err != nil {
		ctx.AbortWithStatus(http.StatusInternalServerError)
		return
	}

	// 获取文件的MIME类型
	mimeType := http.DetectContentType(content[:512])

	// 使用 c.Data() 发送图片二进制数据
	ctx.Data(http.StatusOK, mimeType, content)
}
